#ifndef ISOP_H
#define ISOP_H

#include "def.h"
#include "vec.h"


class Truth_Table // size 12 byte
{
   private:
   Truth_Table( uint64_t * t , unsigned v ):_data( t+v ){}
   public:
   uint64_t * _data;

   Truth_Table( uint64_t * d ):_data(d){}
   Truth_Table(){}
   inline const Truth_Table neg( unsigned v )const{ return Truth_Table( _data , v ) ;} 

   inline uint64_t operator[]( unsigned i )const{ return _data[i]; }
   inline uint64_t & operator[]( unsigned i ){ return _data[i]; }
   inline bool isClone( const Truth_Table p )const{ return p._data == _data ; }
};
typedef Truth_Table    bool_t;

class ISOP 
{
   struct SopData
   {
      SopData(){}
      SopData( ushort v , ushort p , ushort n , ushort c )
         :var(v),pos(p),neg(n),none(c),cube(0){}
      unsigned short var;
      unsigned short pos;
      unsigned short neg;
      unsigned short none;
      unsigned cube;
   };
   typedef unsigned short sop_t;
   typedef unsigned short var_t; // there are compare to 0

   bool_t           _c0;                // sharing constant 0
   bool_t           _c1;                // sharing constant 1 

   vec<uint64_t * >   _truth_table_pages; // really data pool
   unsigned         _fun_ptr;           // truth_table allocate 

   vec<bool_t>      _tables;
   vec<bool_t>      _recycleList;
   
   //sop pool 
   vec<SopData>		_sops;// 0 is 0 1 is 1

   void   table_allocate( unsigned n );
   bool_t newTruth( );
   bool_t newTruth( uint64_t );

   void   remove( bool_t );

   void   Morreale_Minato_ISOP( uint64_t f, uint64_t cf , var_t , sop_t & , uint64_t & of);
   void   Morreale_Minato_ISOP_core( const bool_t f, const bool_t cf , var_t , sop_t & , bool_t & of);

   void   merge( var_t v , sop_t a , sop_t b , sop_t & o );
   void   Morreale_Minato_ISOP( const bool_t f, const bool_t cf , var_t , sop_t & , bool_t & of);
   unsigned build_cube( unsigned * mem );

   public:
   //--- Given function then produce the cube at mem (memory must allocated) , 
   //bool_t size large than truth_table_length ! 1<<(v-6)
   unsigned Morreale_Minato_ISOP( const bool_t f, const bool_t cf , var_t , unsigned * mem );

   ISOP();
   ~ISOP();

};

#endif
